Im folgenden die Ausführungen zur Lösung, wenn man keinen Parallelport mehr hat oder der Zugriff darauf erschwert ist. Dazu weitere Bilder und Downloads:
Die Beobachtung der Pegel mit lptchk funktioniert nicht. Die Ausgangspegel brechen zu stark ein.
Das Problem taucht auch bei USB2LPT 1.7 (High-Speed) auf. Ohne lptchk. Hierfür ist eine gesonderte Lösung praktikabel, siehe unten.
Von Leica kommt jener Vorschlag [sic!] um mit 3,3-V-Laptop-LPTs zurechtzukommen. Kann nicht funktionieren, weil ohne Geräteeingriff am Pin 25 gar keine 9 Volt herauskommen. Auch hier wäre der unten angegebene Bustreiber die bessere und die Batterie schonende Lösung.
rundll32.exe .\inpout32.dll,Info qDieses Kommando muss nach Betriebssystemstart, vor dem Starten von wgif12nt, mit Administratorrechten ausgeführt werden. Es sucht vorhandene Parallelports und trägt deren Basisadresse im BIOS-Datenbereich ein, damit diese von wgif12nt.exe gefunden werden können.
Wie der Name BIOS-Datenbereich andeutet, wird dieser vom BIOS gefüllt und benutzt. Derartige PCI- und PCIexpress-Karten tauchen aber erst beim Windows-Hochlauf auf und sind für das BIOS nicht sichtbar.
Alternativ kann man die Lösung für 64-Bit-Windows benutzen, siehe unten.
Der Vorteil von entsprechend geeigneten ExpressCard-Karten ist, dass diese in Notebooks mit passendem Slot laufen und der Zugriff ohne Geschwindigkeitsverlust einhergeht. ExpressCard basiert auf PCIexpress und ist hier gleichbedeutend.
Ungeeignete ExpressCard-Karten sind USB-basiert und ensprechen solchen USB-Parallel-Adaptern, die nur für Drucker geeignet sind.
fpatch.com -s06668b750883e601 -p+7 -r03 WGif12NT.exeSucht nach der angegebenen Bytefolge und ändert das letzte Byte (die Indexmaske) auf 3.
Für 64-Bit-Windows ist noch mehr zu tun, siehe unten.
Daher ist USB2LPT.SYS nunmehr (seit Oktober 2013) so erweitert, dass es den Datenbereich auch unter NT entsprechend patcht. Um sicher zu gehen auch im 64-Bit-Windows. Unter 9x/Me tat es der Treiber immer schon.
Ohne weitere Maßnahmen läuft nur der ATmega8-basierte USB2LPT 1.6 Low-Speed. Wegen seiner 5-V-Pegel. Das Auslesen einer 3-KByte-Datei dauert damit ca. 10 Minuten. Unter Windows 2000 oder XP. Unter Windows Vista und 7 noch einiges langsamer. Wegen der verbotenen BULK-Pipes.
Damit USB2LPT 1.7 High-Speed läuft, muss:
.dll
entfallen.
Herr Markus Neu
hatte bei sich den Suffix zwingend gebraucht, was ich nicht nachvollziehen kann.
Der Vorsatz .\
sorgt dafür, dass InpOut32.dll nicht zuerst im Pfad gesucht wird,
sondern nur die Datei im aktuellen Verzeichnis benutzt wird.
Sonst würde eine eventuell bereits global installierte ältere InpOut32.dll
im %SystemRoot%\SysWOW64
-Verzeichnis stören.
rundll32.exe .\InpOut32.dll,CatchIo WGif12NT.exeAdmin-Rechte sind beim erstmaligen Start erforderlich, um den enthaltenen Treiber inpoutx64.sys zu laden. Die Dateien giveio.sys und mapmem.sys kann man getrost löschen, da sie unter 64-Bit-Windows schlichtweg unbrauchbar sind.
Im Falle von PCI/PCIexpress-Karten wird das Aktualisieren des BIOS-Datenbereiches nicht benötigt. Damit LPT3 funktioniert, ist ein Patch (siehe oben) vonnöten. Im übrigen funktioniert diese Lösung auch unter 32-Bit-Windows, ohne Aktualisierung des BIOS-Datenbereiches.
USB2LPT funktioniert damit auch. Allerdings benötigt sein Treiber (zurzeit) den deaktivierten Treiberzertifizierungszwang. Dazu ist bei jedem Booten von Windows Vista oder 7 F8 zu drücken und der entsprechende Menüpunkt auszuwählen. Bei Windows 8 sowie 8.1 ist das Prozedere noch komplizierter. Zwar funktioniert USB2LPT inzwischen auch ohne Treiber, ist dann aber viel langsamer.
Zunächst funktionierte die Lösung nicht, weil der Zugriff auf den BIOS-Datenbereich bei vorgegaukeltem Windows 9x Schutzverletzungen (Exceptions) hervorbrachte. Die aktuelle Version von inpout32.dll verarbeitet jede Art von Ladebefehl aus dem BIOS-Bereich. Dazu ist ein entsprechender X86-Befehlsdekoder eingebaut.
Neu: Es steht ein 64-bittriges giveio.sys zur Verfügung, mit dem Portzugriffe aus dem User-Mode ohne Zeitverzug durch das Exception-Handling möglich sind. Er erweist sich als funktionssicher und ist sogar zertifiziert. Diese Variante ist nunmehr zu bevorzugen.
Das Verständnis der Datenübertragung und des Speicherformates ist die einzige Chance, das Gerät wirklich und dauerhaft in die Zukunft zu retten. Alles andere (auch USB2LPT) ist auf Dauer nur ein Herumstümpern. Auf 16 KByte kann ja nicht so viel sein, und das DOS-Programm ist nicht allzu kompliziert. Natürlich ist die Echse mit einem Exe-Packer bearbeitet worden, aber das ist ja für den Durchschnittshacker kaum ein Problem. Die Disassemblierung der wesentlichen Bestandteile muss folgende Teile offenlegen:
Die Datenkompression erfolgt anscheinend nach diesem Schema:
Das Dateisystem besteht aus einem 256-Byte-Wurzelverzeichnis mit 13 für den Anwender nutzbaren nummerierten „Slots“ (keine Dateinamen) mit festlegbarer Maximalgröße in KByte-Schritten. (Wer die ganzen KByte aufbürdet ist unklar, möglicherweise benötigt das Vermessungsgerät diese Stückelung.) Die Dateien sind nach derzeitigem Erkenntnisstand immer in 8-Byte-Stückelung.
Hier noch mal das IDA5-Projekt der DOS-Software.
Ein bestens konstruierter USB-Adapter sollte ohne speziell zugeschnittene Anwendersoftware auskommen. Damit kann man auf die Daten unabhängig vom Betriebssystem zugreifen. Die Mikrocontroller-Software fällt dafür komplexer aus. Dafür gibt es zwei Implementierungsmöglichkeiten:
Beide Ansätze erfordern eine Hintertür zur Speicherplatzreservierung. Die Unterstützung diverser Schutzattribute ist nicht möglich und ohnehin obsolet.
habe ich mich dazu aufgerappelt, das Media Transfer Protocol in einen ATmega32U4 auf einem Arduino Pro Micro zu implementieren. Der Arduino-Urlader wurde durch meinen Ableger von ubaboot ersetzt: Er ist mit 0,5 KByte schön klein. Da die Firmware nicht größer als 7,5 KByte groß wird, dienen die restlichen 24 KByte als Datenspeicher.
Wenn man das Gehäuse einer GRM10-Speicherkarte mit dem 3D-Drucker nachahmt und eine geeignete Leiterplatte macht, kann man sich so eine neues Medium bauen, das:
Genial, nicht wahr? Jetzt wird bloß noch Zeit und ein Vermessungsgerät zum Testen benötigt, denn die serielle Schnittstelle zum Vermessungsgerät hin muss ja auch noch ausgeschnüffelt und nachgeahmt werden. Und Zeit zum Programmieren.
Firmware, funktioniert wie ein 24-Kilobyte-USB-Stick. Benötigt mein ubaboot als Urlader und läuft auf ATmega32U4 mit 16-MHz-Quarz. Die gleiche Firmware auf's Notwendige eingedampft, bei gleicher Funktionalität unter Windows 10. Vor allem beim RAM-Verbrauch wurde erheblich reduziert.
Ausgangspunkt war eine Teensy-Firmware für einen 32-Bit-Controller, die hiermit für die 8-Bit-Architektur zurechtgestutzt und speziell für den ATmega32U4 angepasst wurde, um nicht zu fett zu werden. Außerdem ist's so verständlicher geworden.
Wie man leicht erkennt, bietet sich MTP auch für Datenlogger an. Diese müssten dann readonly sein und können die Excel-ASCII-Daten auf Abruf von einem hochdichten Logspeicher auspacken und ausspucken.
Lange habe ich damit gekämpft, das Flash-Schreiben hinzubekommen:
Die Firmware verlässt sich nun voll und ganz auf den Mini-Urlader
ubaboot für do_spm()
.
Andere Schwierigkeiten waren Bugs, Bugs und noch mehr kleine Käferchen.
Ist nunmehr alles gelöst.
Zugegeben, den Urlader ubaboot auf einen Arduino draufzubringen ist nichts für Anfänger. Wäre es nicht schön, den bereits vorhandenen Urlader Caterina nutzen zu können? Klar, der verbraucht 2 Kilobyte Flash, nicht nur 512 Byte. Na gut.
Der entscheidende Punkt ist, eine Adresse für do_spm herauszufinden. Da vom Urlader keine Disassemblerlistings im Web herumgeistern, sondern nur HEX-Dateien, muss man:
Das Disassemblieren mit Bordmitteln erfordert das Überführen der HEX-Datei in eine ELF-Datei, und das geht wie folgt:
avr-objcopy -I ihex -O elf32-avr --rename-section .sec1=.text,contents,alloc,load,readonly,code Caterina-Micro.hex Caterina-Micro.elf avr-objdump -d Caterina-Micro.elf > Caterina-Micro.lst
Alternativ geht auch:
avr-objcopy -I ihex -O elf32-avr Caterina-Micro.hex Caterina-Micro.elf avr-objdump -D Caterina-Micro.elf > Caterina-Micro.lst
Der Disassembler disassembliert stupid alles zu Assemblerbefehlen. Er hat keine Kodepfadanalyse.
Der Befehl spm kommt dabei ziemlich oft vor.
Das kommt vom #include <avr/boot.h>
.
Keiner davon hat ret
in der Nähe,
das heißt, es ist kein Unterprogramm vorhanden,
sondern alles inline
.
Das hätte man auch nach dem Studium des Quelltextes Caterina.c
in Verbindung mit avr/boot.h herausfinden können.
Ende Gelände, Aus die Maus!
Dieser Urlader wird original von Atmel in den Chips ausgeliefert und zwackt 4 KByte von den 32 KByte ab. Auf PC-Seite gibt dieser sich als „hersteller-spezifisch“ aus und wird per Atmels INF-Datei an libusb gebunden. Im Geräte-Manager steht „Atmel DFU“. Auf Arduino-Boards wurde dieser durch den Arduino-Hersteller durch Caterina überschrieben. Daher findet sich dieser Urlader nur in unverlöteten Chips sowie auf Entwicklungsboards, die nicht auf Arduino basieren, etwa dem eHaJo-Board, wie er im Projekt Frequenzmesser verwendet wurde.
Die gleiche Prozedur wurde an der Datei
ATMega32U4-usbdevice_dfu-1_0_0.hex ausgeführt,
die man als megaUSB_DFU_Bootloaders.zip von AtmelMicrochip
herunterladen kann.
Die habe ich mal disassembliert.
Dabei zeigt sich, dass man hier nicht nur passende Einsprungpunkte findet,
sondern am Ende des Urladers eine Sprungtabelle extra für diesen Zweck existiert.
7fe4: jmp 0x7dda ;Flash-Page löschen (SPMCSR = 3) + Schreiben (SPMCSR = 5) + Rücksprung (SPMCSR = 0x11), Z in R17:R16 7fe8: jmp 0x7e22 ;Signatur lesen (SPMCSR = 0x21), Z in R17:R16, Ergebnis in R16 7fec: jmp 0x7e32 ;Sperrbits lesen (SPMCSR = 9), Z in R17:R16, Ergebnis in R16 7ff0: jmp 0x7e42 ;Wort in Flash setzen (SPMCSR = 1), Wort in R17:R16, Z in R19:R18 7ff4: jmp 0x7de4 ;Flash-Page schreiben (SPMCSR = 5) und Rücksprung (SPMCSR = 0x11), Z in R17:R16 7ff8: jmp 0x7e06 ;Flash-Page löschen (SPMCSR = 3) und Rücksprung (SPMCSR = 0x11), Z in R17:R16 7ffc: jmp 0x7e52 ;Sperrbits setzen (SPMCSR = 9), Sperrbits in R16
Das Code-Wirrwarr kann weder durch Assembler noch avr-gcc entstanden sein. Atmel hat das wohl eher mit IAR „verbrochen“. (Immerhin sind die vielen Unterprogrammaufrufe alle mit RCALL, nicht mit CALL gemacht.) Alle 7 Unterprogramme warten vorher und nachher auf das Ende des Flash-Vorgangs (SPMCSR.0 = 0), aber nicht auf den EEPROM. R0, R20 sowie Z werden „verbraten“.
Zumindest für den Convac-Ätzer bietet es sich an, den 1-KByte-EEPROM künftig nicht mehr mit der seriellen Schnittstelle und CDC abzubilden, sondern als eine einzige Datei mittels MTP. In diesem Fall zum Lesen und Schreiben. Dann hat man eine einfache Backup- und Restore-Möglichkeit für die mühsam eingegebenen Daten.
Da die Firmware bereits elend groß ist, wäre es nunmehr wichtig, diese Funktionalität kleiner als CDC hinzubekommen. Am meisten könnte man an der Bereitstellung der Deskriptoren sparen. Für jenes Projekt.
Herausgekommen ist dieses MTP-Gerät mit 1,5 KByte Größe. Es ist ein Readonly-Gerät mit genau 1 Datei von 1 KByte, die den Inhalt des EEPROM wiedergibt. Nicht sonderlich hilfreich, aber ein Gradmesser: Die MTP-Routinen erstrecken sich von 0x014A bis 0x031E, das sind 0x1D6 Bytes, weniger als 1/2 Kilobyte. Aber Readonly ist nicht so recht nützlich.
Die konsequente Weiterentwicklung ist das MTP-Gerät mit 1 veränderbaren Datei. Leider lässt es sich nicht vermeiden, dass der Anwender diese Datei „erfolgreich löschen“ darf und kann. Sie verschwindet von der Explorer-Ansicht, obwohl sie weiterhin existiert, wie man durch Ab- und Anstecken verifizieren kann. Auch diesmal reflektiert die Datei den EEPROM-Inhalt, diesmal in variabler Länge von 0 bis 1024. Die MTP-Routinen erstrecken sich von 0x0464 bis 0x06F6, das sind 0x292 Bytes, knapp 3/4 Kilobyte. Nicht schlecht. Der avr-gcc-Schalter -mrelax hilft.
Da man dazu das Protokoll zwischen TheodolitenTachymeter
und Speicherkarte ausforschen muss, muss man die Arbeit eines Vermessers zumindest in den bedientechnischen Grundzügen
und bei den verwendeten Dateiformaten verstehen.
Dazu eine Linksammlung:
Typ | Kapazität | Vorteile | Nachteile | Favorit Nr. |
---|---|---|---|---|
STM32F103C8T6 auf
BluePill,
auch einzeln | 48 KByte? oder 64 KByte? |
|
| 4 |
AT90USB1286 | 64 KByte |
|
| 6 |
ATxmega128A4U | 64 KByte |
|
| 7 |
ATmega32U4 | 24 KByte |
|
| 5 |
ATmega32U4 auf Pro Micro | 24 KByte |
|
| 1 |
ATmega32U2 | 24 KByte |
|
| 3 |
8 KByte |
|
| - | |
PIC16F1454 + 24LC512 | 64 KByte |
|
| 2 |
Ich werde die feste Speicherplatzreservierung des Originals durch eine dynamische ersetzen: Das Feature kannte man ja bereits bei CP/M! Dadurch ist es wesentlich leichter möglich, mit nur 24 KByte sinnvoll arbeiten zu können. Man bedenke, dass der Speicherplatzbedarf durch die o.a. Kompression nur etwa die Hälfte der Größe der .GRE-Dateien betragen wird. Es kann aber auch sein, dass das Tachymeter damit nicht zurechtkommt.
Dank USB ist der Datenzugriff ein Fingerschnipp! Es wird kein gesondertes (Windows-)Programm zum Zugriff benötigt, der Explorer genügt. Es funktioniert auch unter Linux, mit dem Total Commander, und das sogar live, d.h. wenn die Karte im Tachymeter steckt und man gerade Daten aufzeichnet. Wie oben angeführt sind die Daten auf dem NOR-Flash des Mikrocontrollers ungleich sicherer vor Lesefehlern als auf NAND-Flash üblicher Speicherkarten.
Die Speicherkarte wird mit dem 3D-Drucker nachempfunden. Die Originalfarbe ist in etwa dunkelkhaki. Eine Platineneinlage mit Ausschnitt für die USB-Buchse ermöglicht den einfachen Platineneinbau ohne allzu filigranen 3D-Druck. Die Platine selbst ist dann ausschließlich einseitig SMD-bestückt. Es passt ein Pro Micro oder ein PIC18F25K50 sowie etwas Fußvolk hinein. Mit Pro Micro ist die USB-Buchse auf Micro-B (wie bei Smartphones) festgelegt. Bei PIC18F25K50 würde ich mich auf Mini-B (wie bei Navis) festlegen.
GRM10-Protokolldekoder für sigrok/PulseView in Entwicklung bzw. ausreichend fertig. Dazu ein 3D-gedrucktes Gehäuse für den Billigst-Logikanalysator. Die Bitrate = Taktrate liegt bei etwas unter 100 kHz, die Abfragerate = Frequenz auf der SEL-Leitung liegt bei 1 kHz. Da das 1 KByte/s entspricht wäre ein 24-KByte-Speicher in 24 s so seriell auslesbar. Wie man im PulseView sieht werden nach der Adresse 4 weitere Takte mit gesonderter Bedeutung ausgesendet:
Der Karten-Anwesenheitstest wird durch Senden von 39990-0-0 (0x9C36-0-0) bewerkstelligt. Die Batterieprüfung wird durch 0x8000-1-1 vollzogen. Kommt da ein NAK, kommt Battery Low. Bei defektem MBR kommt REC ACCESS ERROR BAD HEADER bzw. Error76 am Tachymeter. Dafür kann man echt Kohle loswerden, wie dort beschrieben.
📱Zur Äpp (unfertig) — Derzeitiger Entwicklungsstand der Firmware (unfertig)